package com.cheer.ba.app.oss;

import android.content.Context;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.text.TextUtils;
import android.util.Log;
import android.widget.ImageView;

import com.alibaba.sdk.android.oss.ClientException;
import com.alibaba.sdk.android.oss.ServiceException;
import com.alibaba.sdk.android.oss.callback.OSSCompletedCallback;
import com.alibaba.sdk.android.oss.internal.OSSAsyncTask;
import com.alibaba.sdk.android.oss.model.PutObjectRequest;
import com.alibaba.sdk.android.oss.model.PutObjectResult;
import com.cheer.ba.utils.ImageUtils;
import com.litesuits.common.utils.FileUtil;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class UploadPicManager {

    //上下文
    private Context mContext;
    //oss上传前缀路径地址
    public static String OSS_HOST;
    //oss上传后缀路径地址
    public static String OSS_LAST_PATH;

    public ConcurrentHashMap<String, OSSAsyncTask> concurrentHashMap = new ConcurrentHashMap<>();

    //确定需要上传的文件
    List<UploadInfo> mRequestUploadList;

    //存储上传成功的文件
    private List<UploadInfo> mResultList;

    //文件上传成功回调
    private OnUploadCallback mOnUploadCallback;

    public interface OnUploadCallback {
        /**
         * @param result     是否上传成功
         * @param resultList 上传文件列表
         */
        void onResult(boolean result, List<UploadInfo> resultList);
    }

    public UploadPicManager() {
        mResultList = new ArrayList<UploadInfo>();
    }

    public UploadPicManager(OnUploadCallback onUploadCallback) {
        mOnUploadCallback = onUploadCallback;
        mResultList = new ArrayList<UploadInfo>();
    }

    /**
     * 上传类
     */
    public static class UploadInfo {
        //标识
        public Object tag;
        //路径
        public String fileSavePath;

        @Override
        public String toString() {
            return "UploadInfo{" +
                    "tag=" + tag +
                    ", fileSavePath='" + fileSavePath + '\'' +
                    '}';
        }
    }

    /**
     * 图片质量压缩和上传
     *
     * @param context     上下文
     * @param uploadInfos 需要上传文件的列表
     * @param objectDir   oss服务器对应文件夹名称
     * @param mImgView    需要缩放图片
     */
    public void compressAndUploads(Context context, List<UploadInfo> uploadInfos, String objectDir, ImageView mImgView) {
        this.mContext = context;
        compressImage(context, uploadInfos, objectDir, mImgView);
    }

    /**
     * 自动缩放图片
     * 图片大小和质量压缩
     *
     * @param context    上下文
     * @param resultList 需要上传文件的列表
     * @param objectDir  oss服务器对应文件夹名称
     */
    private void compressImage(final Context context, List<UploadInfo> resultList, final String objectDir, final ImageView mImgView) {
        new AsyncTask<List<UploadInfo>, Void, List<UploadInfo>>() {

            @Override
            protected void onPreExecute() {
                super.onPreExecute();
            }

            @Override
            protected List<UploadInfo> doInBackground(List<UploadInfo>... params) {
                List<UploadInfo> list = null;
                try {
                    list = params[0];
                    if (null != list) {
                        for (int i = 0; i < list.size(); i++) {
                            UploadInfo mInfo = list.get(i);
                            String path = mInfo.fileSavePath;
//                            if (null != mImgView) {
//                                Bitmap bitmap = ImageUtils.autoResizeFromLocalFile(path, mImgView);
//                                path = ImageUtils.saveBitmap(mContext, bitmap);
//                            }
                            if (!path.contains(".mp4")) {
                                Bitmap result = ImageUtils.getImage(path);
                                File file = ImageUtils.compressBmpToFile(context, result, OssManager.HEADIMAGE.equals(objectDir) ? 10 : 200);
                                if (file != null && file.exists()) {
                                    mInfo.fileSavePath = file.getAbsolutePath();
                                }
                            }
                            mInfo.tag = i;
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    return null;
                }
                return list;
            }

            @Override
            protected void onPostExecute(List<UploadInfo> s) {
                super.onPostExecute(s);
                if (s != null) {
                    uploads(context, s, objectDir);
                } else {
                    if (mOnUploadCallback != null) {
                        mOnUploadCallback.onResult(false, null);
                    }
                }
            }
        }.execute(resultList);
    }

    /**
     * 文件上传
     *
     * @param context     上下文
     * @param uploadInfos 需要上传文件的列表
     * @param objectDir   oss服务器对应文件夹名称
     */
    public void uploads(Context context, List<UploadInfo> uploadInfos, String objectDir) {
        this.mRequestUploadList = uploadInfos;
        concurrentHashMap.clear();
        mResultList.clear();

        String uuid = null;
        for (int i = 0; i < uploadInfos.size(); i++) {
            UploadInfo mSuccessUpload = new UploadInfo();
            //需要上传路径
            String requestUploadPath = uploadInfos.get(i).fileSavePath;

            uuid = UUID.randomUUID().toString();
            if (requestUploadPath.contains(".mp4")) {
                OSS_LAST_PATH = "android/" + objectDir + uuid + requestUploadPath.substring(requestUploadPath.lastIndexOf("."));
            } else {
                if (requestUploadPath.lastIndexOf(".") != -1) {
                    OSS_LAST_PATH = "android/" + OssManager.PIC + objectDir + uuid + requestUploadPath.substring(requestUploadPath.lastIndexOf("."));
                } else {
                    OSS_LAST_PATH = "android/" + OssManager.PIC + objectDir + uuid;
                }
            }
            if (!requestUploadPath.contains("http")) {
                //当为本地地址时才送oss服务器上传
                OSSAsyncTask task = OssManager.uploadFile(requestUploadPath, OSS_LAST_PATH, objectDir, new CustomCallBack(uuid));
                concurrentHashMap.put(uuid, task);
                mSuccessUpload.fileSavePath = OSS_LAST_PATH;
                mSuccessUpload.tag = i;
            } else {
                //网络地址直接作为结果保存
                mSuccessUpload.fileSavePath = requestUploadPath;
                mSuccessUpload.tag = i;
            }
            mResultList.add(mSuccessUpload);
        }
        checkResult();
    }


    public List<String> syncUploads(Context context, List<String> uploadStrs, String objectDir) throws ClientException, ServiceException, IOException {
        this.mContext = context;
        OSS_HOST = "http://" + OssManager.bucketName + "." + OssManager.endpoint + "/";
        concurrentHashMap.clear();
        mResultList.clear();
        String uuid = null;
        String objectKey = null;
        List<String> uploadResultList = new ArrayList<>();
        for (int i = 0; i < uploadStrs.size(); i++) {
            uuid = UUID.randomUUID().toString();
            if (uploadStrs.get(i).lastIndexOf(".") != -1) {
                objectKey = OssManager.PIC + objectDir + uuid + uploadStrs.get(i).substring(uploadStrs.get(i).lastIndexOf("."));
            } else {
                objectKey = OssManager.PIC + objectDir + uuid;
            }
            if (!uploadStrs.get(i).contains("http")) {
                //当为本地地址时才送oss服务器上传
                String result = OssManager.syncUploadFile(uploadStrs.get(i), objectKey, objectDir);
                FileUtil.deleteFile(new File(uploadStrs.get(i)));
                if (!TextUtils.isEmpty(result)) {
                    uploadResultList.add(OSS_HOST + objectKey);
                } else {
                    return null;
                }
            } else {
                //网络地址直接作为结果保存
                uploadResultList.add(uploadStrs.get(i));
            }
        }
        return uploadResultList;
    }

    public List<String> compressAndUploadsSync(Context context, List<String> uploadInfos, String objectDir) throws ClientException, ServiceException, IOException {
        List<String> list = new ArrayList<>();
        if (uploadInfos != null) {
            for (int i = 0; i < uploadInfos.size(); i++) {
                Bitmap result = ImageUtils.getImage(uploadInfos.get(i));
                File file = ImageUtils.compressBmpToFile(context, result, OssManager.HEADIMAGE.equals(objectDir) ? 10 : 200);
                if (file != null && file.exists()) {
                    String str = file.getAbsolutePath();
                    list.add(str);
                } else {
                    return null;
                }
            }
            return syncUploads(context, list, objectDir);
        }
        return null;
    }

    public static ExecutorService executorService = Executors.newFixedThreadPool(9);

    /**
     * oss文件上传回调
     */
    public class CustomCallBack implements OSSCompletedCallback<PutObjectRequest, PutObjectResult> {

        private String uuid;


        public CustomCallBack(String uuid) {
            this.uuid = uuid;
        }


        @Override
        public void onSuccess(final PutObjectRequest putObjectRequest, PutObjectResult putObjectResult) {
            Log.d("huangqiang", "uploadSuccess uuid is  -- " + uuid);
            Log.d("huangqiang", "uploadSuccess getUploadFilePath " + putObjectRequest.getUploadFilePath());
            concurrentHashMap.remove(uuid);
            checkResult();
            new AsyncTask<Void, Void, Void>() {
                @Override
                protected Void doInBackground(Void... params) {
                    try {
                        FileUtil.deleteFile(new File(putObjectRequest.getUploadFilePath()));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return null;
                }
            }.executeOnExecutor(executorService);
        }

        @Override
        public void onFailure(final PutObjectRequest putObjectRequest, ClientException e, ServiceException e1) {
            Log.d("huangqiang", "uploadFailure uuid is  -- " + uuid);
            Log.d("huangqiang", "uploadFailure  -- " + e.getMessage());
            Log.d("huangqiang", "uploadFailure  -- " + e1.getMessage());
            new AsyncTask<Void, Void, Void>() {

                @Override
                protected Void doInBackground(Void... params) {
                    try {
                        FileUtil.deleteFile(new File(putObjectRequest.getUploadFilePath()));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return null;
                }
            }.executeOnExecutor(executorService);
            notifyError();
            cancelAll();
        }

    }

    private void checkResult() {
        if (concurrentHashMap.size() == 0) {
            if (mOnUploadCallback != null) {
                mOnUploadCallback.onResult(true, mResultList);
            }
        }
    }

    private void cancelAll() {
        java.util.Iterator it = concurrentHashMap.entrySet().iterator();
        while (it.hasNext()) {
            java.util.Map.Entry<String, OSSAsyncTask> entry = (java.util.Map.Entry) it.next();
            entry.getValue().cancel();
            it.remove();
        }
    }

    private void notifyError() {
        if (mOnUploadCallback != null) {
            mOnUploadCallback.onResult(false, null);
        }
    }

}
